a1e541
@@ -151,7 +151,7 @@
public static void main(String[] args) {
     // -h
     if (cmdLine.hasOption('h')) {
       printUsage(options, ss.out);
-      System.exit(0);
+      sysExit(ss, 0);
     }
 
     // -e
@@ -162,7 +162,7 @@
public static void main(String[] args) {
     if (execString != null && fileName != null) {
       ss.err.println("The '-e' and '-f' options cannot be specified simultaneously");
       printUsage(options, ss.err);
-      System.exit(1);
+      sysExit(ss, 1);
     }
 
     // -p
@@ -180,24 +180,45 @@
public static void main(String[] args) {
     // all done parsing, let's run stuff!
 
     if (execString != null) {
-      System.exit(processLine(execString));
+      sysExit(ss, processLine(execString));
     }
 
     try {
       if (fileName != null) {
-        System.exit(processFile(fileName));
+        sysExit(ss, processFile(fileName));
       }
     } catch (FileNotFoundException e) {
       ss.err.println("Input file not found. (" + e.getMessage() + ")");
-      System.exit(1);
+      sysExit(ss, 1);
     } catch (IOException e) {
       ss.err.println("Could not open input file for reading. (" + e.getMessage() + ")");
-      System.exit(1);
+      sysExit(ss, 1);
     }
 
     // -h
     printUsage(options, ss.err);
-    System.exit(1);
+    sysExit(ss, 1);
+  }
+
+  /**
+   * Wrapper for System.exit that makes sure we close our SessionState
+   * before we exit. This ignores any error generated by attempting to
+   * close the session state, merely printing out the error. The return
+   * code is not changed in such an occurrence because we want to retain
+   * the success code of whatever command we already ran.
+   */
+  private static void sysExit(SessionState ss, int retCode) {
+    try {
+      ss.close();
+    } catch (IOException e) {
+      // If we got an error attempting to ss.close, then it's not likely that
+      // ss.err is valid. So we're back to System.err. Also, we don't change
+      // the return code, we simply log a warning, and return whatever return
+      // code we expected to do already.
+      System.err.println(e.getMessage());
+      e.printStackTrace(System.err);
+    }
+    System.exit(retCode);
   }
 
   private static void setConfProperties(HiveConf conf, Properties props) {
@@ -271,7 +292,7 @@
private static int processCmd(String cmd) {
 
     if (ret != 0) {
       driver.close();
-      System.exit(ret);
+      sysExit(ss, ret);
     }
 
     ArrayList<String> res = new ArrayList<String>();
@@ -324,22 +345,22 @@
private static void validatePermissions(CliSessionState ss, HiveConf conf, Strin
       fp = new FsPermission(Short.decode("0" + perms));
     } else {
       ss.err.println("Invalid permission specification: " + perms);
-      System.exit(1);
+      sysExit(ss,1);
     }
 
     if (!HCatUtil.validateMorePermissive(fp.getUserAction(), fp.getGroupAction())) {
       ss.err.println("Invalid permission specification: " + perms + " : user permissions must be more permissive than group permission ");
-      System.exit(1);
+      sysExit(ss,1);
     }
     if (!HCatUtil.validateMorePermissive(fp.getGroupAction(), fp.getOtherAction())) {
       ss.err.println("Invalid permission specification: " + perms + " : group permissions must be more permissive than other permission ");
-      System.exit(1);
+      sysExit(ss,1);
     }
     if ((!HCatUtil.validateExecuteBitPresentIfReadOrWrite(fp.getUserAction())) ||
       (!HCatUtil.validateExecuteBitPresentIfReadOrWrite(fp.getGroupAction())) ||
       (!HCatUtil.validateExecuteBitPresentIfReadOrWrite(fp.getOtherAction()))) {
       ss.err.println("Invalid permission specification: " + perms + " : permissions must have execute permissions if read or write permissions are specified ");
-      System.exit(1);
+      sysExit(ss,1);
     }
 
     conf.set(HCatConstants.HCAT_PERMS, "d" + fp.toString());
